﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace WindowsAPI
{
    class WinAPI
    {
        public const int WM_COPYDATA = 0x004A;
        public const int WM_WATCHDOG = 0x0123;

        [DllImport("User32.dll ", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32")]
        public static extern bool OpenIcon(IntPtr hwnd);

        [DllImport("user32")]
        public static extern bool SetForegroundWindow(IntPtr hwnd);

        /// <summary>
        /// 发送 WM_COPYDATA 消息的数据结构体
        /// </summary>
        [StructLayout (LayoutKind .Sequential)]
        public struct COPYDATASTRUCT
        {
            /// <summary>
            /// 用户自定义数据
            /// </summary>
            public IntPtr dwData;

            /// <summary>
            /// 数据长度
            /// </summary>
            public int cbData;

             /// <summary>
            /// 数据地址指针
            /// </summary>
            public IntPtr lpData;


        }
 

        /// <summary>
        /// 发送 Windows 消息方法
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="msg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport ("user32.dll" , EntryPoint = "SendMessage" , SetLastError = true )]
        public static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);


        /// <summary>
        /// 通过 SendMessage 向指定句柄发送数据
        /// </summary>
        /// <param name="hWnd"> 接收方的窗口句柄 </param>
        /// <param name="dwData"> 附加数据< /param>
         /// <param name="lpdata"> 发送的数据 </param>
        public static int SendCopyData(IntPtr hWnd, int dwData, byte [] lpdata)
        {
            COPYDATASTRUCT cds = new COPYDATASTRUCT();

            cds.dwData = (IntPtr )dwData;

            cds.cbData = lpdata.Length;

            cds.lpData = Marshal .AllocHGlobal(lpdata.Length);

            Marshal .Copy(lpdata, 0, cds.lpData, lpdata.Length);

            IntPtr lParam = Marshal .AllocHGlobal(Marshal .SizeOf(cds));

            Marshal .StructureToPtr(cds, lParam, true );
 

            int result = 0;

            try
            {
                result = SendMessage(hWnd, WM_COPYDATA, IntPtr .Zero, lParam);

            }
            finally
            {
                Marshal .FreeHGlobal(cds.lpData);                 

                Marshal .DestroyStructure(lParam, typeof (COPYDATASTRUCT));
                
                Marshal .FreeHGlobal(lParam);

            }

            return result;
    
        }

        /// <summary>
        /// 获取消息类型为 WM_COPYDATA 中的数据
        /// </summary>
        /// <param name="m"></param>
        /// <param name="dwData"> 附加数据 </param>
        /// <param name="lpdata"> 接收到的发送数据 </param>
        public static void ReceivCopyData(ref System.Windows.Forms.Message m, out int dwData, out byte[] lpdata)
        {
            COPYDATASTRUCT cds = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));

            dwData = cds.dwData.ToInt32();

            lpdata = new byte[cds.cbData];

            Marshal.Copy(cds.lpData, lpdata, 0, cds.cbData);

            m.Result = (IntPtr)0;

        }

        //查找指定进程的窗口句柄  
        public static IntPtr GetProcessHandle(string processName)
        {
            //进程是否正在运行
            //string vshostName = string.Format("{0}.vshost", processName);
            string vshostName = string.Format("{0}", processName);

            IntPtr hWnd = IntPtr.Zero;
            Process[] processOnComputer = Process.GetProcesses();
            foreach (System.Diagnostics.Process p in processOnComputer)
            {
                if (p.ProcessName.Equals(processName) || p.ProcessName.Equals(vshostName))
                {
                    hWnd = p.MainWindowHandle;
                    break;
                }
            }

            return hWnd;
        }
    }
}
